5-1 }x}堨

依儲存方式的不同,MATLAB 的矩陣可分為兩種:完全矩陣(Full Matrix)與稀疏矩陣(Sparse Matrix), 一般我們看到的 MATLAB矩陣都是完全矩陣,其中每一個元素都存成 double 的資料型態,佔用 8 個 Byte, 因此一個 m×n 的完全矩陣,所佔用的記憶體空間是 8×m×n 個 Byte。但在稀疏矩陣中,由於大部分的元素都是0, 因此只須儲存「非零元素的位置」及其「元素值」即可,這種特殊的內部儲存方式有下列兩大優點:

  1. 節省記憶體儲存空間。
  2. 節省許多不必要的運算。

MATLAB 的 sparse 指令可將一個完全矩陣轉換成稀疏矩陣,例如:

Example 1: 05-稀疏矩陣/sparse01.mA = [1 0 0 0 0; 0 0 0 3 0; 0 4 0 0 0]; % 完全矩陣 S = sparse(A) % 將完全矩陣 A 轉換成稀疏矩陣 SS = (1,1) 1 (3,2) 4 (2,4) 3

由此可看出,S 是一個稀疏矩陣,MATLAB 只儲存其各個非零元素的位置(即其二維下標 (1,1)、(3,2)、(2,4)) 和元素值(1、4、3)。若要比較矩陣 A 和 S 所佔用的記憶體大小,可輸入如下:

Example 2: 05-稀疏矩陣/sparse02.mclear all; % 清除所有的變數 A = [1 0 0 0 0; 0 0 0 3 0; 0 4 0 0 0]; % 完全矩陣 S = sparse(A); % 將完全矩陣 A 轉換成稀疏矩陣 S whos Name Size Bytes Class Attributes A 3x5 120 double S 3x5 96 double sparse

由此可驗證稀疏矩陣 S 佔用記憶體的位元組數目(96 Bytes)比矩陣 A(120 Bytes)小很多。

我們也可以使用 sparse 指令來直接產生稀疏矩陣,其使用語法如下:

S = sparse(i, j, s, m, n);

其中 i 是列索引,j 是行索引,s 是非零元素所形成的向量,m 是 s 的列維度,n 是 s 的行維度。 i、j、s 都是長度相同的向量,s(k) 的二維下標即是 i(k)及 j(k)。例如,以下語法可以產生與前例相同的稀疏矩陣 S:

Example 3: 05-稀疏矩陣/sparse03.mS = sparse([1 3 2], [1 2 4], [1 4 3], 3, 5);

您也可以在 sparse 指令加上第六種輸入變數,代表最多可以容納的非零元素個素,使得您可以後續再加入非零元素, 而不必改變整個稀疏矩陣的結構。

MATLAB 提供了另一個指令 spdiags,可由對角線元素來建構一個稀疏矩陣,其一般格式如下:

S = spdiags(D, d, m, n)

其中 D 的每一個直行代表矩陣的對角線向量,d 代表對角線的位置(0 代表主對角線,-1 代表向下位移一單位的次對角線, 1 代表向上位移一單位的次對角線,依此類推),m 與 n 則分別代表矩陣的列維度與行維度。例如:

Example 4: 05-稀疏矩陣/spdiags01.mD = [2 7; 4 9; 1 3]; d = [1 -1]; S = spdiags(D, d, 4, 3) A = full(S)S = (2,1) 7 (1,2) 4 (3,2) 9 (2,3) 1 (4,3) 3 A = 0 4 0 7 0 1 0 9 0 0 0 3

由此可看出 D 的兩個行向量 [2 4 1]' 及 [7 9 3]',分別是矩陣 A 的兩個對角線向量,一個位於主對角線之上,另一個位於主對角線之下。(但在矩陣 D 的第一行向量中,我們只用到了第二及第三個元素,第一個元素則因超越矩陣邊界範圍而被「砍掉了」!)

一般的 load 及 save 指令,也可以處理稀疏矩陣,並儲存於二進制的 MAT 檔案。另一個常用到的指令是 spconvert, 可將一個 m×3 的矩陣轉換成稀疏矩陣,其中第一直行代表列索引,第二直行代表行索引,第三直行則是非零的元素值。 例如:

Example 5: 05-稀疏矩陣/spconvert01.mload spmat.dat spmat S = spconvert(spmat)spmat = 1 1 2 3 2 4 2 4 1 8 3 5 S = (1,1) 2 (3,2) 4 (8,3) 5 (2,4) 1

在上述範例中,spmat 的第一及第二直行代表稀疏矩陣的橫列索引及直行索引,第三直行則是元素值,經由 spconvert,我們即可建構此稀疏矩陣。
MATLAB程式設計:進階篇